using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using CSRedis;
using System.Data.SqlClient;

namespace 校验重复请求.Controllers
{
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        private static CSRedisClient RedisClient { get; set; }
        private string ConnectionString = "Data Source=localhost;Initial Catalog=Test;User=sa;Password=Ewell@123;Packet Size=512";
        public WeatherForecastController()
        {
            RedisClient = new CSRedisClient("127.0.0.1:6379,password=123456");
        }
        /// <summary>
        /// 用户预约
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public Response MakeAnAppointment([FromBody] UserAppointmentRequest request)
        {
            var result = new Response();
            var key = request.IdCard+request.DateTime;
            var value = SetWhenNotExist(key,"0",DateTime.Now.AddSeconds(5));
            if (value)
            {
                //在这里执行唯一请求操作
                var json = JsonConvert.SerializeObject(request);
                //测试保存数据到数据库
                ExcuteSQL(request.UserName);

                Console.WriteLine(json);
                result.Message=json;
                RedisClient.Del(key);
                return result;
            }
            else
            {
                result.Message="此乃重复请求";
                return result;
            }
        }

        [HttpPost]
        public void ExcuteSQL(string json)
        {
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                // 打开数据库连接
                connection.Open();

                // 开始一个新的事务
                SqlTransaction transaction = connection.BeginTransaction();

                try
                {
                    // 创建SQL命令对象
                    SqlCommand cmd = new SqlCommand();
                    cmd.Connection = connection;
                    cmd.Transaction = transaction;

                    // 构造SQL语句（注意：此处应使用参数化查询防止SQL注入）
                    string sql = "insert into BaseInfo values('1',@json)";
                    cmd.CommandText = sql;

                    // 添加参数
                    cmd.Parameters.AddWithValue("@json", json);

                    // 执行更新操作
                    int rowsAffected = cmd.ExecuteNonQuery();

                    // 如果到这里没有抛出异常，则提交事务
                    transaction.Commit();
                    Console.WriteLine("转账成功，受影响行数：" + rowsAffected);
                }
                catch (Exception ex)
                {
                    // 如果有任何错误，回滚事务
                    Console.WriteLine("发生错误，正在进行事务回滚...");
                    if (transaction != null)
                    {
                        transaction.Rollback();
                    }
                    Console.WriteLine("转账失败，错误详情：" + ex.Message);
                }
            }
        }

        /// <summary>
        /// 用户预约
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public Response MakeAnAppointment1(UserAppointmentRequest request)
        {
            var result = new Response();
            var key = request.IdCard+request.DateTime;
            RedisClient.Set(key, 0, TimeSpan.FromSeconds(5));
            var value = RedisClient.IncrBy(key);
            if (value>1)
            {
                result.Message="此乃重复请求";
                return result;
            }
            else
            {  
                //在这里执行唯一请求操作
                var json = JsonConvert.SerializeObject(request);
                Console.WriteLine(json);
                result.Message=json;
                RedisClient.Del(key);
                return result;
            }
        }
        public bool SetWhenNotExist<T>(string key, T t, DateTime expire)
        {
            if (typeof(T) == typeof(string))
            {
                return RedisClient.Set(key, t.ToString(), expire - DateTime.Now, RedisExistence.Nx);
            }
            else
            {
                return RedisClient.Set(key, System.Text.Json.JsonSerializer.Serialize(t), expire - DateTime.Now, RedisExistence.Nx);
            }
        }

        public new class Response
        {
            public string? Message { get; set; }
        }
        /// <summary>
        /// 用户预约请求信息
        /// </summary>
        public class UserAppointmentRequest
        {
            /// <summary>
            /// 姓名
            /// </summary>
            public string UserName { get; set; }
            /// <summary>
            /// 身份证号
            /// </summary>
            public string IdCard { get; set; }
            /// <summary>
            /// 预约日期（yyyy-MM-dd）
            /// </summary>
            public string DateTime  { get; set; }
        }
    }
}
